import React, { useState, useEffect } from 'react';
import { Upload, Modal, message } from 'antd';
import { ToTopOutlined } from '@ant-design/icons';
import request from 'umi-request';
import styles from './index.less';
import { queryOssSign } from './utils/service';

// 生成上传图片的名字
const getFileName = (file) => {
  const { name = '', uid, type } = file;
  return `${name.split(".")[0]}_${uid}.${type.split("/")[1]}`
}

// 校验图片的高宽比
const validImageWH = (file, width, height) => {
  const filereader = new FileReader();
  const image = new Image();

  return new Promise((resolve, reject) => {
    if (!width || !height) {
      resolve(true);
    } else {
      filereader.onload = e => {
        image.onload = function () {
          // 获取图片的宽高，并存放到file对象中
          if (this.width !== width || this.height !== height) {
            message.error(`图片尺寸大小应为：${width}*${height}`);
            reject(false);
          } else resolve(true);
        };
        image.onerror = reject;
        image.src = e.target.result;
      };
      filereader.readAsDataURL(file);
    }
  });
};

// OSS直传
const uploadOSS = async (file, fileList, onChange, separator) => {
  try {
    const { success, data } = await queryOssSign();
    if (success) {
      const { host, dir } = data;
      const name = getFileName(file);
      let formData = new FormData();

      formData.append("key", `${data.dir}${name}`); // 文件名字，可设置路径
      formData.append("policy", data.policy); // policy规定了请求的表单域的合法性
      formData.append("OSSAccessKeyId", data.accessid); // Bucket 拥有者的Access Key Id。
      formData.append("success_action_status", '200'); // 让服务端返回200,不然，默认会返回204
      formData.append("signature", data.signature); //根据Access Key Secret和policy计算的签名信息，OSS验证该签名信息从而验证该Post请求的合法性
      // formData.append("callback", data.callback);
      formData.append('file', file); //需要上传的文件 file 

      request(data.host, { method: 'post', data: formData }).then(res => {
        const newFileList = [
          ...fileList,
          {
            uid: file.uid,
            url: `${host}${dir}${name}`,
            name,
            status: 'done',
          }
        ];

        onChange && onChange(newFileList.map(el => el.url).join(separator));
      })
    }
  } catch (error) {
    console.log(error)
  }
}

const ImgUpload = ({
  value,
  separator,
  onChange,
  size,
  width,
  height,
  disabled,
  hideUploadButton,
  max,
  accept,
  tabelShow, }) => {

  const [fileList, setFileList] = useState([]);

  // value值变化更改fileList
  useEffect(() => {
    if (value) {
      const arr = value.split(separator); // 接受多张图片数据
      const res = [];
      Object.keys(arr).forEach(key => {
        res.push({
          uid: key,
          url: arr[key],
          name: `${key}.png`,
          status: 'done',
        });
      });
      setFileList(res);
    } else {
      setFileList([]);
    }
  }, [value]);

  // 预览
  const handlePreview = file => {
    Modal.info({
      title: '图片预览',
      icon: false,
      content: (<img alt="图片预览" style={{ width: '100%' }} src={file.url} />),
      okText: '关闭',
      width: 600
    });
  };

  // 移除
  const handleRemove = file => {
    let arr = [];
    if (value) arr = value.split(separator);
    const res = arr.filter(item => item !== file.url);
    onChange(res.join(separator));
  };

  // 上传文件之前的钩子
  const handleBeforeUpload = async (file) => {
    const isLegal = file.type === 'image/jpeg' || file.type === 'image/png';
    if (!isLegal) {
      message.error('图片文件必须是jpg、png！');
    }

    const isLt3M = file.size / 1024 / 1024 < size;
    if (!isLt3M) {
      message.error(`图片文件必须小于${size}MB!`);
    }

    const measure = true; //await validImageWH(file, width, height); // 宽高限制

    if (isLegal && isLt3M && measure) {

      // 替换默认的上传方法
      let reader = new FileReader();
      reader.readAsDataURL(file);
      reader.onloadend = () => {
        uploadOSS(file, fileList, onChange, separator);
      }
    }
    return false;
  };

  const uploadButton = (
    <div className={styles.defaultUploadWrap}>
      <ToTopOutlined style={{ fontSize: '18px' }} />
      <div className="ant-upload-text">上传</div>
    </div>
  );

  return (
    <div className={tabelShow ? styles.imgUploadWrapSmall : styles.imgUploadWrap}>
      <Upload
        accept={accept}
        listType="picture-card"
        fileList={fileList}
        onPreview={handlePreview}
        onRemove={handleRemove}
        beforeUpload={handleBeforeUpload}
        disabled={disabled}
        showUploadList={{
          showPreviewIcon: true,
          showRemoveIcon: !disabled,
          showDownloadIcon: false,
        }}
      >
        {fileList.length >= max || hideUploadButton ? null : uploadButton}
      </Upload>

      {/* 提示语 */}
      <p className={`tip ${tabelShow ? 'hide' : ''}`}>
        {`只支持${accept}文件,大小不超过${size}mb`}
        {width ? `,图片尺寸为${width}*${height}` : ''}
      </p>
    </div>
  );
};

ImgUpload.defaultProps = {
  disabled: false, // 是否可以删除重新上传
  hideUploadButton: false, // 是否隐藏上传按钮，默认否
  size: 3, // 上传图片的大小，单位为M
  max: 1, // 最多可上传几张图片，默认1张
  accept: '.jpg,.png', // 可接收类型
  width: '', // 尺寸宽度
  heigth: '', // 尺寸高度
  separator: ';', // 多图片值分隔符
  tabelShow: false, // 是否在表格展示
  onChange: () => { }, // 图片上传变化回调
};

export default ImgUpload;
